/* Hello World Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "esp_sleep.h"
#include "time.h"
#include "esp_sntp.h"
#include "nvs_flash.h"
#include "esp_netif.h"

#include "lvgl/lvgl.h"
#include "port/disp_driver.h"
#include "apps/sgf_lvgl.h"
#include "apps/sgf_sensor.h"
#include "net/sgf_web.h"
#include "net/sgf_wifi.h"
#include "net/sgf_http.h"
#include "sys/sgf_cfg.h"
#include "sys/sgf_time.h"


sgf_info_t info;
int wait_second = 0;
int sleep_second = 0;
static const char *TAG = "main";

SemaphoreHandle_t sem_got_ip;

#define DISP_BUF_SIZE (400 * 300)

int get_reset_push()
{
    if (ESP_RST_POWERON == esp_reset_reason()) {
        return 1;
    }
    return 0;
}


void gpio_weekup_init_s(uint64_t s)
{
    ESP_LOGI(TAG, "sleep");
    esp_deep_sleep_enable_gpio_wakeup(BIT(GPIO_NUM_4), ESP_GPIO_WAKEUP_GPIO_LOW);
    esp_deep_sleep(s * 1000 * 1000);
    esp_deep_sleep_start();
}

static void gui_task(void* pvParameter)
{
    lv_init();

    lv_color_t* buf = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
    assert(buf != NULL);

    disp_driver_init();
    static lv_disp_draw_buf_t disp_buf;

    uint32_t size_in_px = DISP_BUF_SIZE;

    lv_disp_draw_buf_init(&disp_buf, buf, NULL, size_in_px);

    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);

    disp_drv.flush_cb = disp_driver_flush;
    disp_drv.hor_res = 400;
    disp_drv.ver_res = 300;
    disp_drv.full_refresh = 1;
    disp_drv.draw_buf = &disp_buf;

    lv_disp_drv_register(&disp_drv);
    sgf_lvgl_display(&info);
    lv_refr_now(NULL);
    if (wait_second != 0) {
        ESP_LOGI(TAG, "wait=%ds", wait_second);
        vTaskDelay(pdMS_TO_TICKS(1000 * wait_second));
    }
    gpio_weekup_init_s(sleep_second);
}

static void gpio_task(void* pvParameter)
{
    int gpio_status = 1;
    int delay = 0;
    gpio_sleep_set_direction(GPIO_NUM_4, GPIO_MODE_INPUT);
    gpio_sleep_set_pull_mode(GPIO_NUM_4, GPIO_PULLUP_ENABLE);
    while(1) {
        vTaskDelay(pdMS_TO_TICKS(100));
        gpio_status = gpio_get_level(GPIO_NUM_4);
        if (gpio_status == 0) {
            ESP_LOGI(TAG, "gpio pushed");
            delay++;
        } else {
            delay = 0;
        }
        if (delay > 20) {
            ESP_LOGI(TAG, "reset wifi");
            sgf_wifi_reset();
            sgf_cfg_reset();
            vTaskDelay(pdMS_TO_TICKS(100));
            esp_restart();
        }
    }
}


void app_main(void)
{
    sem_got_ip = xSemaphoreCreateBinary();
    memset(&info, 0, sizeof(info));
    xTaskCreatePinnedToCore(gpio_task, "gpio_task", 4096, NULL, 5, NULL, 1);
    sleep_second = 60 * 60 * 4;
    wait_second = 0;

    sgf_wifi_init();
    if(sgf_cfg_init() != 0) {
        sleep_second = 60 * 60 * 12;
        wait_second = 300;
        strcpy(info.remind, "请连接sfg_ap热点\n然后通过浏览器访问\n192.168.4.1");
        sgf_wifi_set_ap();
        sgf_web_init();
    } else {
        if (strlen(sgf_get_wifi_ssid())) {
            sgf_wifi_set_station(sgf_get_wifi_ssid(), sgf_get_wifi_passwd());
            if (xSemaphoreTake(sem_got_ip, pdMS_TO_TICKS(60000)) == pdTRUE) {
                info.wifi = 100;
                sleep_second = 60 * 60 * 4;
                sgf_http_get_weather(&info, sgf_get_http_code(), sgf_get_http_key());
                sgf_http_get_code(&info, NULL);
                if (get_reset_push() == 1) {
                    wait_second = 300;
                    sgf_web_init();
                }
            } else {
                ESP_LOGI(TAG, "wifi connected failed");
                info.wifi = -1;
                strcpy(info.remind, "一不小心，网络失联了");
            }
        } else {
            sgf_time_get(&info);
            if (get_reset_push() == 1) {
                wait_second = 300;
                sgf_wifi_set_ap();
                sgf_web_init();
            }
        }
    }
    xTaskCreatePinnedToCore(gui_task, "gui_task", 4096 * 2, NULL, 5, NULL, 1);
}
